突然發覺後面幾天好像都只是結合前面學習的組合技,或是以另一種方式呈現而已,所使用到的 Web API 及操作都大同小異,想到拖曳功能立馬聯想到 Day11 客製化影片播放器的影片進度條拖曳功能,有一句名言叫做不要「重造輪子」,因此我決定拿前面的程式碼過來進行改寫。
// 先宣告一個變數存放上次的滑鼠X座標
let lastX = 0;
// 取得包含所有item的容器節點
const div = document.querySelector(".items");
// 滑鼠按下時才新增 滑鼠移動的事件監聽器以及新增active class
slider.addEventListener("mousedown", handleMouseDown);
function handleMouseDown(e) {
// 每次觸發後複寫現在觸發的X值,供 mousemove handler計算使用
lastX = e.clientX;
slider.classList.add("active");
slider.addEventListener("mousemove", handleDrag);
}
// 滑鼠彈起 及 滑鼠離開progressContainer容器則會將滑鼠移動的監聽器移除,以及移除active class
slider.addEventListener("mouseup", removeListener);
slider.addEventListener("mouseleave", removeListener);
function removeListener(params) {
slider.removeEventListener("mousemove", handleDrag);
slider.classList.remove("active");
}
與作者使用狀態切換去判斷要不要滾動不同的是,我改用mousedown
時才會新增mousemove
的事件監聽器,滑鼠彈起或離開容器時則會再將這個mousemove
的事件監聽器移除,這樣會相對節省一些效能
handleDrag
: 將父層容器的左邊滾動偏移量加上上次鼠標位置減去現在觸發位置,有可能是負值(上次 X 值為:100 往往右滑 X 值:120 滑動),等於 scrollLeft-20,這邊需要反向思考,如有不懂可使用 console.log()印出來方便理解。function handleDrag(e) {
slider.scrollLeft += lastX - e.clientX;
// 最後再將這次的X值賦值回去給下一次事件觸發使用
lastX = e.clientX;
}